﻿using Capstone.Models;
using Capstone.Views;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using Xamarin.Auth;
using Xamarin.Forms;

namespace Capstone.ViewModels
{
    public class LoginViewModel : BaseViewModel
    {
        public Command LoginGoogleCommand { get; }
        public Command LoginAppleCommand { get; }
        public LoginViewModel()
        {
            LoginGoogleCommand = new Command(OnLoginGoogleClicked);
            LoginAppleCommand = new Command(OnLoginAppleClicked);
        }

        private async void OnLoginAppleClicked(object obj)
        {
            // Prefixing with `//` switches to a different navigation stack instead of pushing to the active one
            await Shell.Current.GoToAsync($"//{nameof(AboutPage)}");
        }

        private void OnLoginGoogleClicked()
        {

            var authenticator = new OAuth2Authenticator
                         (
                           clientId: "387664376312-19vdmrnqaihaalimrjn07spe5qtitm46.apps.googleusercontent.com",
                           clientSecret: null,
                           scope: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
                           authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/auth"),
                           redirectUrl: new Uri("com.companyname.capstone:/oauth2redirect"),
                           accessTokenUrl: new Uri("https://oauth2.googleapis.com/token"),
                           isUsingNativeUI: true
                          );

            authenticator.AllowCancel = true;

            AuthenticationState.Authenticator = authenticator;

            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            presenter.Login(authenticator);

            authenticator.Completed += async (senders, obj) =>
            {
                if (obj.IsAuthenticated)
                {
                    var clientData = new HttpClient();

                    // Call Google API to fetch logged in user profile information
                    var resData = await clientData.GetAsync("https://www.googleapis.com/oauth2/v3/userinfo?access_token=" + obj.Account.Properties["access_token"]);
                    var jsonData = await resData.Content.ReadAsStringAsync();

                    // Deserialize the JSON data and intilize in GoogleAuth
                    GoogleAuth googleObject = JsonConvert.DeserializeObject<GoogleAuth>(jsonData);

                    // You can access following information after login
                    Application.Current.Properties["Name"] = googleObject.Name;
                    Application.Current.Properties["Email"] = googleObject.Email;
                    Application.Current.Properties["Access_token"] = obj.Account.Properties["access_token"];
                    Application.Current.Properties["Access_token_exp"] = DateTime.UtcNow + TimeSpan.FromSeconds(Convert.ToDouble(obj.Account.Properties["expires_in"]));
                    Application.Current.Properties["Refresh_token"] = obj.Account.Properties["refresh_token"];
                    Application.Current.Properties["Refresh_token_exp"] = DateTime.UtcNow + TimeSpan.FromDays(7);

                    await Shell.Current.GoToAsync($"//{nameof(AboutPage)}");
                }
                else
                {
                    await App.Current.MainPage.DisplayAlert("Error", "Authentication failed", "OK");
                }
            };
        }

        public async void NewAccessToken()
        {
            string jsonFormat = "{ \"client_id\":\"387664376312-19vdmrnqaihaalimrjn07spe5qtitm46.apps.googleusercontent.com\",\"client_secret\":\"\",\"refresh_token\":\"" + Application.Current.Properties["Refresh_token"] + "\",\"grant_type\":\"refresh_token\" }";

            var client = new HttpClient();
            var response = await client.PostAsync("https://oauth2.googleapis.com/token", new StringContent(jsonFormat, Encoding.UTF8, "application/json"));
            var jsonData = await response.Content.ReadAsStringAsync();
            Auth authObject = JsonConvert.DeserializeObject<Auth>(jsonData);

            Application.Current.Properties["Access_token"] = authObject.Access_token;
            Application.Current.Properties["Access_token_exp"] = DateTime.UtcNow + TimeSpan.FromSeconds(Convert.ToDouble(authObject.Expires_in));
        }
    }
}
